﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using YiShop.Framework.Constants;
using YiShop.System.Constants;
using YiShop.System.Entities;
using YiShop.System.Repositories;

namespace YiShop.System.Services
{
    public class SysUserService : BaseService<SysUser, SysUserDto>
    {
        private readonly ICache _cache;
        private readonly ILogger<SysUserService> _logger;
        private readonly SysUserRepository _sysUserRepository;
        private readonly SysUserPostRepository _sysUserPostRepository;
        private readonly SysUserRoleRepository _sysUserRoleRepository;

        public SysUserService(ICache cache, SysUserRepository sysUserRepository, ILogger<SysUserService> logger, SysUserPostRepository sysUserPostRepository, SysUserRoleRepository sysUserRoleRepository)
        {
            _cache = cache;
            _sysUserRepository = sysUserRepository;
            _logger = logger;
            BaseRepo = sysUserRepository;
            _sysUserPostRepository = sysUserPostRepository;
            _sysUserRoleRepository = sysUserRoleRepository;
        }

        /// <summary>
        /// 查询 用户信息表 详情
        /// </summary>
        public async Task<SysUserDto> GetDtoAsync(long? id)
        {
            var dto = new SysUserDto { UserId = id ?? 0 };
            var user = await _sysUserRepository.GetUserDtoAsync(dto);
            return user;
        }

        /// <summary>
        /// 校验用户是否有数据权限
        /// </summary>
        /// <param name="userId">用户id</param>
        public async Task CheckUserDataScope(long userId)
        {
            if (!SecurityUtils.IsAdmin(SecurityUtils.GetUserId()))
            {
                SysUserDto dto = new SysUserDto { UserId = userId };
                List<SysUser> users = await GetListAsync(dto);
                if (users.IsEmpty())
                {
                    throw new ServiceException("没有权限访问用户数据！");
                }
            }
        }

        /// <summary>
        /// 校验用户是否允许操作
        /// </summary>
        /// <param name="user"></param>
        public void CheckUserAllowed(SysUserDto user)
        {
            if (user.UserId > 0 && SecurityUtils.IsAdmin(user.UserId))
            {
                throw new ServiceException("不允许操作超级管理员用户");
            }
        }

        /// <summary>
        /// 校验用户名称是否唯一
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        public async Task<bool> CheckUserNameUniqueAsync(SysUserDto user)
        {
            var userDto = await _sysUserRepository.GetUserByUserNameAsync(user.UserName!);
            if (userDto != null && userDto.UserId != user.UserId)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 校验手机号码是否唯一
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        public async Task<bool> CheckPhoneUniqueAsync(SysUserDto user)
        {
            var dto = new SysUserDto { Phonenumber = user.Phonenumber, DelFlag = DelFlag.No };
            var userDto = await _sysUserRepository.GetUserDtoAsync(dto);
            if (userDto != null && userDto.UserId != user.UserId)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 批量删除用户信息
        /// </summary>
        public virtual async Task<int> DeleteUserByIdsAsync(List<long> userIds)
        {
            foreach (long userId in userIds)
            {
                CheckUserAllowed(new SysUserDto { UserId = userId });
                await CheckUserDataScope(userId);
            }
            // 删除用户与角色关联
            await _sysUserRoleRepository.DeleteUserRole(userIds);
            // 删除用户与岗位关联
            await _sysUserPostRepository.DeleteUserPost(userIds);
            return _sysUserRepository.DeleteUserByIds(userIds);
        }

        /// <summary>
        /// 校验email是否唯一
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        public async Task<bool> CheckEmailUniqueAsync(SysUserDto user)
        {
            var dto = new SysUserDto { Email = user.Email, DelFlag = DelFlag.No };
            var userDto = await _sysUserRepository.GetUserDtoAsync(dto);
            if (userDto != null && userDto.UserId != user.UserId)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 新增保存用户信息
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        public virtual async Task<bool> InsertUser(SysUserDto user)
        {
            // 新增用户信息
            user.Password = MD5Encryption.Encrypt(user.Password!);
            user.DelFlag = DelFlag.No;
            bool succees = await InsertAsync(user);
            // 新增用户岗位关联
            await InsertUserPost(user);
            // 新增用户与角色管理
            await InsertUserRole(user);
            return succees;
        }

        /// <summary>
        /// 新增用户岗位信息
        /// </summary>
        /// <param name="user"></param>
        public async Task InsertUserPost(SysUserDto user)
        {
            if (user.PostIds.Count > 0 )
            {
                // 新增用户与岗位管理
                List<SysUserPost> list = new List<SysUserPost>();
                foreach (long postId in user.PostIds)
                {
                    SysUserPost up = new SysUserPost();
                    up.UserId = user.UserId;
                    up.PostId = postId;
                    list.Add(up);
                }
                await _sysUserPostRepository.InsertAsync(list);
            }
        }

        /// <summary>
        /// 新增用户角色信息
        /// </summary>
        /// <param name="user"></param>
        public async Task InsertUserRole(SysUserDto user)
        {
            if (user.RoleIds.IsNotEmpty())
            {
                // 新增用户与角色管理
                List<SysUserRole> list = new List<SysUserRole>();
                foreach (long roleId in user.RoleIds)
                {
                    SysUserRole ur = new SysUserRole();
                    ur.UserId = user.UserId;
                    ur.RoleId = roleId;
                    list.Add(ur);
                }
                await _sysUserRoleRepository.InsertAsync(list);
            }
        }

        /// <summary>
        /// 修改保存用户信息
        /// </summary>
        public virtual async Task<int> UpdateUser(SysUserDto user)
        {
            // 删除用户与角色关联
             await _sysUserRoleRepository.DeleteUserRoleByUserId(user.UserId);
            // 新增用户与角色管理
            await InsertUserRole(user);
            // 删除用户与岗位关联
            await _sysUserPostRepository.DeleteUserPostByUserId(user.UserId);
            // 新增用户与岗位管理
            await InsertUserPost(user);

            return await _sysUserRepository.UpdateUser(user);
        }

        //获取登录信息
        public LoginUser GetLoginUser(HttpRequest request)
        {
            // 获取请求携带的令牌
            string token = SecurityUtils.GetToken(request);

            var claims = SecurityUtils.ParseToken(token);
            // 解析对应的权限以及用户信息
            string uuid = claims.Where(c => c.Type.Equals(GlobalConstants.LOGIN_USER_KEY)).First().Value;
            string userKey = CacheConstants.LOGIN_TOKEN_KEY + uuid;
            LoginUser user = _cache.Get<LoginUser>(userKey);
            return user;
        }

        //获取登录ID
        public string GetLoginUserId(HttpRequest request)
        {
            // 获取请求携带的令牌
            string token = SecurityUtils.GetToken(request);

            var claims = SecurityUtils.ParseToken(token);
            // 解析对应的权限以及用户信息
            return claims.Where(c => c.Type.Equals(DataConstants.USER_ID)).First().Value;

        }

        //删除登录信息
        public void DelLoginUser(string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                string userKey = CacheConstants.LOGIN_TOKEN_KEY + token;
                _cache.Remove(userKey);
            }
        }

        /// <summary>
        /// 查询 用户
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns></returns>
        public async Task<SysUserDto> GetDtoByUsernameAsync(string username)
        {
            var dto = new SysUserDto { UserName = username, DelFlag = DelFlag.No };
            var user = await _sysUserRepository.GetUserDtoAsync(dto);
            return user;
        }

        internal async void InsertUserAuth(long userId, List<long> roleIds)
        {
            await _sysUserRoleRepository.DeleteUserRoleByUserId(userId);
            InsertUserRole(userId, roleIds);
        }

        /// <summary>
        /// 新增用户角色信息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="roleIds">角色组</param>
        private async void InsertUserRole(long userId, List<long> roleIds)
        {
            if (roleIds.IsNotEmpty())
            {
                // 新增用户与角色管理
                List<SysUserRole> list = new List<SysUserRole>();
                foreach (long roleId in roleIds)
                {
                    SysUserRole ur = new SysUserRole();
                    ur.UserId = userId;
                    ur.RoleId = roleId;
                    list.Add(ur);
                }
                await _sysUserRoleRepository.InsertAsync(list);
            }
        }

    }
}

